STEP 4:SCRIPTING
Now we are going to do the hard part of this tut, the script.
You should get some coffee or something you will need it! I've
been doing script for a long time so this is fairly easy for
me. I'll try to explain every line carefully so that you understand
everything that is being done and so that you don't simply
copy everything without understanding anything.
Ok, the lines in blue are just to explain the next line so
don't write them in your script, the lines in red are to show
you an alternate way of doing things and script lines are
underline in gray.
First open notepad (I use TextPad) and write these lines.
They are the same as in any script (until the Fire_Flak88
thread) so they don't really need any explaining…
// File: Tutorial.scr Title of the
file
// Authors: Kalahad Who made it
// Date: 00/00/00 The date you did the script
main:
setcvar "g_scoreboardpic"
"none"
level waitTill prespawn
exec global/DMprecache.scr
level.script = maps/dm/Tutorial.scr
exec global/exploder.scr
You need this line in almost every
script. It's in there that sounds are set for your map. We
will need to modify the ubersound.scr to get the flak88 turning
and firing sound working and also for the explosion sound.
I will show you how a bit later in this tut.
exec ubersound/ubersound.scr
level waittill spawn
end
Now, the hard part :
This is the part where we make the
flak88 work correctly. If you remember we put a setthread
"Fire_Flak88" in the trigger in our map. So when
the player is passing trough the trigger it calls this thread
automatically.
Fire_Flak88:
Now we are going to set some variables.
The keyword "local" mean that the variable created
with this attribute is local to the thread we are working
in. So "local.gun_name" is a variable named "gun_name"
that is local to this thread. You put the name of your gun
in this variable. In our case it is "Flak88_Num1".
Don't forget the "$" before the name or it might
not work correctly.
local.gun_name = $Flak88_Num1
Now we’ll create a variable
that will be use as the target for the gun. In our case it
is the player so we write "$player" (the game engine
know what “player” is) but it could be many other
things like a tank, a position on the map, your old grandmother…
local.target = $player
So now we have 2 variables, the name
of the gun and the name of the target. We have all we need
to point the gun at the target. In the next line you can see
a "setaimtarget", this is a game function that make
the object on the left aim at the object on the right by calling
the right animation. So to point the gun on you we use this
function with the gun name and the target name like in the
next line.
local.gun_name setaimtarget local.target
So now the gun is turning but we have
a small problem. A gun like that take some time to turn around
(it's heavy you know) and if we don't do anything it will
fire before the turning is finish and that doesn't give our
map a very realistic look. So we are going to make the next
part of the script (the firing) wait a bit while the gun is
turning. For this we use "wait(1)", the number in
the () is the number of seconds we want to wait. Since our
gun won't need to turn more than 30° on both sides (the
room is not wide enough for more), 1 second should be enough.
You can change it if you have a gun that can turn more (or
less) than this one.
wait(1)
Here we are creating two variables,
a range and an offset. We don't want the explosion to be always
right on top of the player. A gun like that is not always
very accurate so we are going to do some random calculations
to set the place of the explosion. The range and the offset
are two distances from the player that we will use to set
(randomly) the place off the explosion. Here is a little drawing
I made to explain what are the range and the offset.

So if you look at the next two lines in the script we have
this part "96+randomint(128)" for both of them.
The '96' is a minimal distance from the player so that the
explosion will never be closer than 96 units from him. Don't
worry, with the explosion we are going to make 96 units is
close enough to kill you (twice over). The other part "randomint(128)"
will get an integer (randomly) between 0 and 127. So the explosion
will be at a range of 96 + 0 or +1 or +2 …or +127 from
the player and it will also be at an offset of 96+ 0 or +1
or +2 …or +127 from the player.
local.range = 96 + randomint(128)
local.offset = 96 + randomint(128)
So now we have a range and an offset
for the explosion. Now we need to make the gun fire his shell.
We do this by making the game call an animation "fire_scripted".
We do this by writing the next line. In the game the gun will
get a backward motion from the firing and you will see the
fire and smoke coming out off the gun pipe (Cooooool).
local.gun_name anim fire_scripted
You could also use something like this:
Local.gun startfirring
Wait(0.2)
Local.gun stopfirring
Now we must wait again. We don't want
the explosion to be at the same time that the gun is firing.
To make this realistic we are going to make it a random wait.
You could put in any values you like. If you have a gun that
is at 1500 feet from the target you could put a higher value.
wait( 0.7 + ( ( randomint( 6 ) ) * 0.1)
)
Ok, now we are creating a local variables
"A1" that will be the actual final position of the
explosion. The next line put the explosion right on top of
the player. Here the expression ".origin" is use
to get the origin of the local variable name "target".
Local.A1 = local.target.origin
Ok, now we have a position for the
explosion (A1) but we still have a small problem. We don't
want it to be always on top of the player. So this is where
we will use the range and offset variables that we made earlier.
The range could be in front (positive X values) or on the
back (negative X values) of the target. Same thing for the
offset, it could be on the right (positive Y values) or the
left (negative Y values) of the player. So, if we don't want
the explosion to be always on the back and on the right side
of the player we need to do some modification to our range
and offset values. Remember that our position is a 3 values
set (X Y Z). We won't change the 'z' position because the
explosion will always be at ground level with the target in
this map. In our map, the offset is on the 'Y' axis and the
range is on the 'X' axis. To change the 'X' value of the position
we change the local.A1[0] value, to change the 'Y' value of
the position we change the local.A1[1] value and to change
the 'Z' value of the position we change the local.A1[2] value.
if( (randomint( 100 ) ) < 50 )
local.A1[0] = local.A1[0] + local.range
else
local.A1[0] = local.A1[0] - local.range
if( (randomint( 100 ) ) < 50 )
local.A1[1] = local.A1[1] + local.offset
else
local.A1[1] = local.A1[1] - local.offset
Here is a better (more realistic) way
of doing the same thing. I did not put it in the script because
I don't want to get into the basic of loops and vectors. You
should take a look at this and, if you understand it, you
should use it in your script to replace the last 9 lines we
wrote. This is the way you should use if you want to deal
with the ‘Z’ value of the position
local.vec = vector_normalize
( local.gun_name.origin - ( local.target.origin ) )
local.A1 = vector_scale local.vec local.offset
local. A1 = local. A1 + local.target.origin + ( 0 0 32 )
for ( local.i=0; local.i<2; local.i++ )
{
if ( (randomint 100 ) < 50 )
local. A1 [local.i] = local. A1 [local.i] + randomint( local.range
)
else
local. A1 [local.i] = local. A1 [local.i] - randomint( local.range
)
}
If you do it this way
you will want to use a bigger range value and a bigger offset
value, something like "80+randomint(304)"…
Cool, now we have our final position
for the explosion, it will be inside a square (with 4 sides
of 224 units) around the player position (but not closer than
96 units from him) but we still need an explosion. In the
single player maps the game use the bazooka explosion to create
the explosion for the flak88. I don't know if you've seen
Band of brothers but the flak explosion in the wood near the
city of Foy were a lot bigger, so lets make something big
for our map. To show you the kind of thing you could make
I will use 3 explosions at the same time and on the same spot.
The bazooka explosion because it is nice, the mortar (like
on dday) because it is big and the mortar in the Higgins boat
because it has a lot of fire and a nice ring of smoke. Ok,
let's do it. You need to create 3 local variables (I named
them Exp1, Exp2, Exp3) and assigned them each to a different
animation. You do this by using the 'spawn' keyword and then
the name of the animation (and path) you want (between "").
Just like in the next 3 lines.
local.Exp1 = spawn "fx/scriptbazookaexplosion.tik"
local.Exp2 = spawn "animate/fx_mortar_dirt.tik"
local.Exp3 = spawn "animate/fx_mortar_higgins.tik"
Ok so now we have 3 animations for our
explosion, but we need something more. What happen when there
is an explosion (except dying)? The ground shake!!! We are
going to do this by calling "earthquake.scr". You
do it just like in the next line. The setting ".23 4
0 0" is great but you could try others by trial and error
if you want.
exec global/earthquake.scr .23 4 0 0
Very nice!!! Now we have a gun firing,
a position for the explosion, 3 animations for the explosion
and a ground that shakes. Very cool, the next thing to do
is to set the origin of the 3 animations and start them up.
You do that like this…
local.Exp1.origin = local.A1
local.Exp1 anim start
local.Exp2.origin = local.A1
local.Exp2 anim start
local.Exp3.origin = local.A1
local.Exp3 anim start
This is simply another wait before we
make the gun turn back in its original position.
wait(1)
The next 3 lines are very important.
If we don't do this the effect (damage zone) of the explosion
will stay on the map after the animations are gone. So now
we must remove the 3 Exp variables (Exp1, Exp2 and Exp3) we
used for the explosion.
local.Exp1 remove
local.Exp2 remove
local.Exp3 remove
Note : Some explosion animation have
a damage zone with them, some don’t. If you’re
using an animation that doesn’t have a damage zone you
can set one yourself by writing the next line.
setdamageradius Local.A1.origin 75
200
Where setdamageradius is the game function,
Local.A1.origin is the origin of the damage zone, 75 is the
amount of damage and 200 is the radius around the origin of
the damage zone where the damage is effective.
And now the final detail! Even after
firing the gun turret is following the target (if he wasn’t
blown out of the map). We want the gun turret to turn back
to its original position. So you go back in your map and make
a little 8x8 brush near the player start and then put a script
origin (right click in the 2D view and select script?origin).
Then with it still selected hit 'N' to bring up the entity
window and put a targetname(I use FlakBaseAim). So now we
do a 'setaimtarget' (like at the beginning of the script but
this time on the origin we just create). You
could also use an absolute value for this instead of a script?origin…
local.gun_name setaimtarget $FlakBaseAim
You could use the “clearAimTarget” game class
to do this but, if you do, the gun will stop following the
player but it won’t return in its original position.
end
// Et voilà !!!
Ok, the script is done. Some will say that this script his
to complicated for nothing. I tried to make this more simplistic
but it doesn't look real enough for me when I play it out.
Remember, a nice map his a map that look real. If you want
to hit the target right in the face the first time, you simply
don't use any random values. You just put the explosions animations
at the player position "local.target.origin".
You could do the same thing with a tank turret (with some
minor modifications). You could also make random bombing in
a field. You simply put a trigger in the field, create more
explosion position (with different range and offset) and put
them in a loop. From there it is almost only copy and paste…
You could also make the gunfire randomly around the trigger
instead of the player, this give a chance for the player to
get away after he (or she, we never know!) triggers the gunfire.
You could also make a trigger that is trigger in only one
direction, this way you know which way the player is running
and you can fire in front of him to make him stop or change
direction… You could even make a trigger that his high
enough to be trigger if the player is standing up but not
if he is crouching…
|